import { CanActivate, ExecutionContext, HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common';
import { Observable } from 'rxjs';
import JWT from 'src/utils/jwt';

/**
 * 全局权限验证守卫
 */
@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    Logger.log('------------>>>>进入全局权限守卫');
    // 获取请求对象
    const request = context.switchToHttp().getRequest();
    const response = context.switchToHttp().getResponse();
    // 获取请求头中的token字段
    const token = context.switchToRpc().getData().headers.authorization;
    // 如果白名单内的路由就不拦截直接通过
    if (this.hasUrl(this.urlList, request.url)) {
      return true;
    }
    // 验证token的合理性以及根据token做出相应的操作
    if (token) {
      try {
        const payload = JWT.verify(token);
        // 刷新token
        const newToken = JWT.generate({
          id: payload.id,
          username: payload.username,
        })
        response.header('authorization', newToken)
        // 这里可以添加角色验证
        return true;
      } catch (e) {
        throw new HttpException('登录超时,请重新登录', HttpStatus.UNAUTHORIZED);
      }
    } else {
      throw new HttpException('登录超时,请重新登录', HttpStatus.UNAUTHORIZED);
    }
  };
  // 白名单数组
  private urlList: string[] = [
    '/admin/user/login',
    '/admin/user/verify_code',
    '/admin/upload/file',
    '/admin/books/list',
    '/admin/books/detail/1'
  ];

  // 验证该次请求是否为白名单内的路由
  private hasUrl(urlList: string[], url: string): boolean {
    let flag: boolean = false;
    if (urlList.indexOf(url) >= 0) {
      flag = true;
    }
    return flag;
  }
}
